package com.xwli.javase.thread.synchroniz;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: springcloud
 * @description:
 * @author: xwli
 * @create: 2022-03-12 16:20
 **/
public class SynchronizedExample {

    /**
     * @description:
     * 对于以下代码，使用 ExecutorService 执行了两个线程，
     * 由于调用的是同一个对象的同步代码块，因此这两个线程会进行同步，
     * 当一个线程进入同步语句块时，另一个线程就必须等待。
     * @params: [args]
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:24
     */
    /*public static void main(String[] args) {
        SynchronizedExample e1 = new SynchronizedExample();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> e1.func1());
        executorService.execute(() -> e1.func1());
        executorService.shutdown();
    }*/

    /**
     * @description:
     * 对于以下代码，两个线程调用了不同对象的同步代码块，因此这两个线程就不需要同步。
     * 从输出结果可以看出，两个线程交叉执行。
     * 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
     * @params: [args]
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:25
     */
   /* public static void main(String[] args) {
        SynchronizedExample e1 = new SynchronizedExample();
        SynchronizedExample e2 = new SynchronizedExample();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> e1.func1());
        executorService.execute(() -> e2.func1());
        executorService.shutdown();
    }*/

    /**
     * @description: 同步一个代码块
     * @params: []
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:21
     */
    public void func1() {
        synchronized (this) {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(i + " ");
            }
        }
    }

    /**
     * @description: 同步一个方法
     * @params: []
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:29
     */
    public synchronized void func2() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(i + " ");
        }
    }

    /**
     * @description: 作用于整个类，也就是说两个线程调用同一个类的不同对象上的这种同步语句，也会进行同步。
     * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
     * @params: [args]
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:31
     */
   /* public static void main(String[] args) {
        SynchronizedExample e1 = new SynchronizedExample();
        SynchronizedExample e2 = new SynchronizedExample();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> e1.func3());
        executorService.execute(() -> e2.func3());
        executorService.shutdown();
    }*/

    /**
     * @description: 同步一个类
     * 作用于整个类，也就是说两个线程调用同一个类的不同对象上的这种同步语句，也会进行同步。
     * @params: []
     * @return: void
     * @author: xwli
     * @date: 2022/3/12 16:30
     */
    public void func3() {
        synchronized (SynchronizedExample.class) {
            for (int i = 0; i < 10; i++) {
                System.out.print(i + " ");
            }
        }
    }

     public static void main(String[] args) {
        SynchronizedExample e1 = new SynchronizedExample();
        SynchronizedExample e2 = new SynchronizedExample();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(() -> e1.func4());
        executorService.execute(() -> e2.func4());
        executorService.shutdown();
    }

    /**
    * @description:
     * 同步一个静态方法，效果跟同步一个类一样
     * 作用于整个类，也就是说两个线程调用同一个类的不同对象上的这种同步语句，也会进行同步。
    * @params: []
    * @return: void
    * @author: xwli
    * @date: 2022/3/12 16:33
    */
    public synchronized void func4() {
        for (int i = 0; i < 10; i++) {
            System.out.print(i + " ");
        }
    }
}
